package com.icexxx.litchi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * 端口工具类
 * 
 */
public class LinuxPortUtil {

    public static void close(int port) {
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = runtime.exec("netstat -ntlp | grep \"" + port + "\"");
            try {
                process.waitFor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            InputStream inputStream = process.getInputStream();
            List<String> content = read(inputStream, "UTF-8", port);
            if (content.size() == 0) {
                return;
            } else {
                killWithPid(content);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void killWithPid(List<String> pids) {
        for (String pid : pids) {
            try {
                Runtime.getRuntime().exec("kill -9 " + pid + "");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static List<String> read(InputStream inputStream, String charset, int portOld) {
        List<String> list = new ArrayList<String>();
        String nl = "\r\n";
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charset));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                if (line != null && !"".equals(line) && line.contains("LISTEN")) {
                    sb.append(line);
                    sb.append(nl);
                }
            }
            String content = sb.toString();
            String port = sievePort(content, portOld);
            if (port != null && !list.contains(port)) {
                list.add(port);
            }
            bufferedReader.close();
            return list;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String sievePort(String content, int portOld) {
        if (content == null || "".equals(content)) {
            return null;
        }
        String[] lines = content.split("\r\n");
        String[][] data = new String[lines.length][3];
        for (int i = 0; i < lines.length; i++) {
            String row = lines[i];
            String[] rowData = sieveLine(row);
            if (rowData != null) {
                data[i] = rowData;
            }
        }
        for (int i = 0; i < data.length; i++) {
            String portStr = data[i][0];
            String pid = data[i][1];
            int port = 0;
            try {
                port = Integer.parseInt(portStr);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            if (port == portOld) {
                return pid;
            }
        }
        return null;
    }

    public static String readTxt(InputStream inputStream, String charset) {
        String nl = "\r\n";
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, charset));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
                sb.append(nl);
            }
            bufferedReader.close();
            return sb.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String[] sieveLine(String row) {
        if (row == null || "".equals(row)) {
            return null;
        }
        String[] strs = new String[3];
        int lastIndexOf = row.lastIndexOf("LISTEN");
        if (lastIndexOf == -1) {
            return null;
        }
        if (lastIndexOf + 6 >= row.length()) {
            return null;
        }
        if (lastIndexOf == 0) {
            return null;
        }
        if (row.charAt(lastIndexOf - 1) != ' ' || row.charAt(lastIndexOf + 6) != ' ') {
            return null;
        }
        String left = row.substring(0, lastIndexOf);
        String right = row.substring(lastIndexOf + 6);
        left = left.trim();
        right = right.trim();
        right = right.replace(" ", "");
        String port = sieveLeft(left);
        if (port == null) {
            return null;
        }
        String[] pidData = sieveRight(right);
        if (pidData == null) {
            return null;
        }
        String pid = pidData[0];
        String pName = pidData[1];
        strs[0] = port;
        strs[1] = pid;
        strs[2] = pName;
        return strs;
    }

    private static String[] sieveRight(String str) {
        if (str == null || "".equals(str)) {
            return null;
        }
        int index = str.indexOf("/");
        if (index == -1) {
            return null;
        }
        String[] result = new String[2];
        String left = str.substring(0, index);
        String right = str.substring(index + 1);
        if (left != null && !"".equals(left)) {
            result[0] = left;
            result[1] = right;
        }
        return result;
    }

    private static String sieveLeft(String str) {
        if (str == null || "".equals(str)) {
            return null;
        }
        if (str.startsWith("tcp6")) {
            str = str.substring(4);
        } else if (str.startsWith("tcp")) {
            str = str.substring(3);
        } else {
            return null;
        }
        str = str.trim();
        if (str.startsWith("0")) {
            str = str.substring(1);
        }
        str = str.trim();
        if (str.startsWith("0")) {
            str = str.substring(1);
        }
        str = str.trim();
        int indexOf = str.indexOf(" ");
        if (indexOf == -1) {
            return null;
        }
        str = str.substring(0, indexOf);
        int indexColon = str.lastIndexOf(":");
        if (indexColon == -1) {
            return null;
        }
        str = str.substring(indexColon + 1);
        if (str == null || "".equals(str)) {
            return null;
        }
        return str;
    }
}
